/*******************************************************************************
 * 版权：北京润尼尔网络科技有限公司，保留所有版权<br>
 * 版本：v1.0.0<br>
 * 文件：AbstractEditPart.js<br>
 * 日期：2016年9月20日<br>
 * 作者:王志远<br>
 * 功能：抽象编辑件，作为MVC的Controller，传递Model和Figure操作<br>
 *
 * 修改记录：<br>
 * 日期 描述 更新功能<br>
 ******************************************************************************/

window.makeNamespace(window, "Rainier.UI.V2");

/**
 * 类型名称：Rainier.UI.V2.AbstractEditPart<br>
 * 类型功能：抽象编辑件<br>
 */
Rainier.UI.V2.AbstractEditPart = Rainier.Basic.CompositeObject.extend({
  NAME: "Rainier.UI.V2.AbstractEditPart",

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.init<br>
   * 函数功能：构造函数<br>
   * 异常信息：无<br>
   */
  init: function () {
    this._super();
    this.editPolicies = new draw2d.util.ArrayList(); //编辑策略列表
    this.modelRequestFactory = null; //请求工厂
    this.modelEventHandlderFactory = null; //模型事件处理器工厂
    this.partFactory = null; //编辑器工厂
    this.model = null; //模型实例
    this.figure = null; //图元实例

    //安装默认工厂
    this.installModelRequestFactory(new Rainier.UI.V2.ModelEventRequestFactory());
    this.installModelEventHandlerFactory(new Rainier.UI.V2.ModelEventHandlerFactory());
    this.installEditPartFactory(new Rainier.UI.V2.PartFactory());
  },

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.installModelEventHandlerFactory<br>
   * 函数功能：安装模型事件处理器工厂<br>
   * 参数输入：factory:Rainier.UI.V2.ModelEventHandlerFactory<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  installModelEventHandlerFactory: function (factory) {
    this.modelEventHandlderFactory = factory;
  },

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.installModelRequestFactory<br>
   * 函数功能：安装模型事件请求工厂<br>
   * 参数输入：factory:Rainier.UI.V2.AbstractEditPart.ModelEventRequestFactory<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  installModelRequestFactory: function (factory) {
    this.modelRequestFactory = factory;
  },

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.installEditPartFactory<br>
   * 函数功能：安装编辑件工厂<br>
   * 参数输入：Factory:Rainier.UI.V2.EditPartFactory<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  installEditPartFactory: function (factory) {
    this.partFactory = factory;
  },

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.installEditPolicy<br>
   * 函数功能：安装编辑策略<br>
   * 参数输入：policy:draw2d.policy.EditPolicy<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  installEditPolicy: function (policy) {
    policy.editPart = this;
    this.editPolicies.add(policy);
  },

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.active<br>
   * 函数功能：激活编辑件<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  active: function () {
    if (this instanceof Rainier.UI.V2.ConnectionEditPart) {
      //this.figure.attr('color',"#cc0000");
      this.figure.attr("stroke", 2.5);
    }
    this.model.active(this);
  },

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.deactive<br>
   * 函数功能：失活编辑件<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  deactive: function () {
    if (this instanceof Rainier.UI.V2.ConnectionEditPart) {
      //this.figure.attr('color',"#129CE4");
      this.figure.attr("stroke", 1);
    }
    this.model.deactive(this);
    // window.app.getPropertyComponent().clickToHide();
  },

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.createFigure<br>
   * 函数功能：创建图元<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  createFigure: function () {
    this.fillFigure();
  },

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.unfillFigure<br>
   * 函数功能：取消填充图元附加信息<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  unfillFigure: function () {
    var editpart = this;
    if (this.figure) {
      //重新定义createCommand函数
      this.figure.createCommand = null;

      //安装EditPolicy
      this.editPolicies.each(function (i, e) {
        var figure = editpart.getFigure();
        figure.uninstallEditPolicy(e);
      });

      //添加onSelectionChanged函数
      this.figure.onSelectionChanged = null;

      //添加onUnselectionChanged函数
      this.figure.onUnselectionChanged = null;

      this.figure.off();
    }
  },

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.fillFigure<br>
   * 函数功能：填充图元附加信息<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  fillFigure: function () {
    var editpart = this;
    if (this.figure) {
      //重新定义createCommand函数
      this.figure.createCommand = function (request) {
        return editpart.onRequestCommand(request);
      };

      //安装EditPolicy
      this.editPolicies.each(function (i, e) {
        var figure = editpart.getFigure();
        figure.installEditPolicy(e);
      });

      //添加onSelectionChanged函数
      this.figure.onSelectionChanged = function (emitter, figure) {
        editpart.onFigureSelect(emitter, figure);
      };

      //添加onUnselectionChanged函数
      this.figure.onUnselectionChanged = function (emitter, figure) {
        editpart.onFigureUnselect(emitter, figure);
      };

      this.figure.on("click", $.proxy(this.onFigureClick, this));
      this.figure.on("dblclick", $.proxy(this.onFigureDbclick, this));
      this.figure.on("move", $.proxy(this.onFigureMove, this));
      this.figure.on("resize", $.proxy(this.onFigureResize, this));
      this.figure.on("timer", $.proxy(this.onFigureTimer, this));
      this.figure.on("contextmenu", $.proxy(this.onFigureContextMenu, this));
      this.figure.on("show", $.proxy(this.onFigureShow, this));
      this.figure.on("hide", $.proxy(this.onFigureHide, this));
      this.figure.on("change", $.proxy(this.onFigureChange, this));
    }
  },

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.onFigureChange<br>
   * 函数功能：当图元属性变化时触发此函数<br>
   * 参数输入：emitter<br>
   * 参数输入：figure<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  onFigureChange: function (emitter, figure) {},

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.onFigureHide<br>
   * 函数功能：当图元隐藏时触发<br>
   * 参数输入：emitter<br>
   * 参数输入：figure<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  onFigureHide: function (emitter, figure) {},

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.onFigureShow<br>
   * 函数功能：当图元显示时触发<br>
   * 参数输入：emitter<br>
   * 参数输入：figure<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  onFigureShow: function (emitter, figure) {},

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.onFigureContextMenu<br>
   * 函数功能：当图元右键菜单时触发<br>
   * 参数输入：emitter<br>
   * 参数输入：figure<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  onFigureContextMenu: function (emitter, figure) {},

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.onFigureTimer<br>
   * 函数功能：当图元右定时器到达时触发<br>
   * 参数输入：emitter<br>
   * 参数输入：figure<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  onFigureTimer: function (emitter, figure) {},

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.onFigureResize<br>
   * 函数功能：当图元重新设置大小时触发<br>
   * 参数输入：emitter<br>
   * 参数输入：figure<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  onFigureResize: function (emitter, figure) {
    this.model.setDimension(this.figure.width, this.figure.height, false, this);
  },

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.onFigureMove<br>
   * 函数功能：当图元移动时触发<br>
   * 参数输入：emitter<br>
   * 参数输入：figure<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  onFigureMove: function (emitter, figure) {
    var pos = this.figure.getPosition();
    this.model.setPosition(pos.x, pos.y, false, this);
  },

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.onFigureDbclick<br>
   * 函数功能：当图元双击时触发<br>
   * 参数输入：emitter<br>
   * 参数输入：figure<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  onFigureDbclick: function (emitter, figure) {},

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.onFigureClick<br>
   * 函数功能：当图元单击时触发<br>
   * 参数输入：emitter<br>
   * 参数输入：figure<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  onFigureClick: function (emitter, figure) {},

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.onFigureSelect<br>
   * 函数功能：当图元选中时触发<br>
   * 参数输入：emitter<br>
   * 参数输入：figure<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  onFigureSelect: function (emitter, figure) {
    this.active(this);
  },

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.onFigureUnselect<br>
   * 函数功能：当图元取消选中时触发<br>
   * 参数输入：emitter<br>
   * 参数输入：figure<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  onFigureUnselect: function (emitter, figure) {
    this.deactive(this);
  },

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.createEditPart<br>
   * 函数功能：通过model创建编辑器<br>
   * 参数输入：objModel:ModelProperty<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  createEditPart: function (objModel) {
    if (this.partFactory) {
      return this.partFactory.createObject(objModel);
    }
  },

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.handleModelEvent<br>
   * 函数功能：处理模型事件<br>
   * 参数输入：modelEvent:模型事件<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  handleModelEvent: function (modelEvent) {
    var eventName = modelEvent.getEventName();
    var oldValue = modelEvent.getOldValue();
    var newValue = modelEvent.getNewValue();

    if (eventName === Rainier.UI.V2.AbstractModel.MODEL_EVENT_PROPERTY_VALUE_CHANGED) {
      //暂时还没啥可做
    }

    //处理属性变化事件
    if (eventName === Rainier.UI.V2.AbstractModel.MODEL_EVENT_UI_PROPERTY_CHANGED) {
      var _figure = this.figure;
      $.each(newValue, function (name, value) {
        if (_figure.attr(name) === value) {
          return;
        }
        _figure.attr(name, value);
      });
    }

    //处理位置改变事件
    if (eventName === Rainier.UI.V2.AbstractModel.MODEL_EVENT_POSITION_CHANGED) {
      this.figure.setPosition(newValue.x, newValue.y);
    }

    //处理尺寸改变事件
    if (eventName === Rainier.UI.V2.AbstractModel.MODEL_EVENT_DIMENSION_CHANGED) {
      this.figure.setDimension(newValue.width, newValue.height);
    }
  },

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.onPropertyChange<br>
   * 函数功能：处理模型层事件<br>
   * 参数输入：evt事件<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  onPropertyChange: function (evt) {
    var oldValue = evt.getOldValue();
    var newValue = evt.getNewValue();

    if (newValue.needCommandRequest) {
      var modelEventRequest = this.modelRequestFactory.createRequestByModelEvent(evt, this);
      if (modelEventRequest) {
        var handler = this.modelEventHandlderFactory.createHandler(modelEventRequest);
        if (handler && this.figure) {
          if (this.figure instanceof draw2d.Canvas) {
            this.figure.getCommandStack().execute(handler);
          } else {
            this.figure.getCanvas().getCommandStack().execute(handler);
          }
        } else {
          this.handleModelEvent(evt);
        }
      }
    } else {
      this.handleModelEvent(evt);
    }
  },

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.onRequestCommand<br>
   * 函数功能：当请求命令时发出<br>
   * 参数输入：request<br>
   * 函数返回：draw2d.command.Command<br>
   * 异常信息：<br>
   */
  onRequestCommand: function (request) {
    if (request === null) {
      return null;
    }

    if (request.getPolicy() === draw2d.command.CommandType.MOVE) {
      if (!this.figure.isDraggable()) {
        return null;
      }
      return new Rainier.UI.V2.CommandMove(this);
    }

    if (request.getPolicy() === draw2d.command.CommandType.DELETE) {
      if (!this.figure.isDeleteable()) {
        return null;
      }
      return new Rainier.UI.V2.CommandDelete(this);
    }

    if (request.getPolicy() === draw2d.command.CommandType.RESIZE) {
      if (!this.figure.isResizeable()) {
        return null;
      }
      return new Rainier.UI.V2.CommandResize(this);
    }
    return null;
  },

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.getFigure<br>
   * 函数功能：获取图元<br>
   * 函数返回：draw2d.Figure<br>
   * 异常信息：无<br>
   */
  getFigure: function () {
    return this.figure;
  },

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.getModel<br>
   * 函数功能：获取模型<br>
   * 函数返回：Rainier.UI.V2.AbstractModel<br>
   * 异常信息：无<br>
   */
  getModel: function () {
    return this.model;
  },

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.setModel<br>
   * 函数功能：设置模型<br>
   * 参数输入：model:Rainier.UI.V2.AbstractModel<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  setModel: function (model) {
    this.model = model;
    this.model.addPropertyChangeListener(this.getUuid(), this);
  },

  /**
   * 函数名称：Rainier.UI.V2.AbstractEditPart.setFigure<br>
   * 函数功能：设置图元<br>
   * 参数输入：model:draw2d.Figure<br>
   * 函数返回：无<br>
   * 异常信息：无<br>
   */
  setFigure: function (figure) {
    this.figure = figure;
    this.fillFigure();
  },
});
